package com.ebt.m.activity;

import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.text.Editable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.ebt.m.AppContext;
import com.ebt.m.AppInitService;
import com.ebt.m.R;
import com.ebt.m.account.AccountHttps;
import com.ebt.m.account.json.AccountResponse;
import com.ebt.m.account.json.ValidateCodeCheckResponse;
import com.ebt.m.account.json.ValidateCodeSendResponse;
import com.ebt.m.commons.model.data.BaseDataResult;
import com.ebt.m.commons.utils.NetUtils;
import com.ebt.m.commons.widgets.view.EBTDialog;
import com.ebt.m.customer.util.ToastUtil;
import com.ebt.m.data.bean.UserInfo;
import com.ebt.m.data.middle.EBTGetAdviceInfo;
import com.ebt.m.data.rxModel.api.EBTAPI;
import com.ebt.m.data.rxModel.apibean.ThirtyLoginParam;
import com.ebt.m.event.LoginEvent;
import com.ebt.m.presenter.LoginPresenter;
import com.ebt.m.utils.ConfigData;
import com.ebt.m.utils.CountDownManager;
import com.ebt.m.utils.CountDownManager.CountDownListener;
import com.ebt.m.utils.DataValidation;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.Arrays;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

//模式 1：新增
//模式 2：修改
//  1. 输入要绑定的手机号码
//  2. 检查输入的手机号码是否已经被绑定
//  3. 如果未被绑定，则发送验证码 send
//  4. 将收到的验证码，与第三步返回的validateid，以及手机号码，一并作为参数，check验证是否通过
public class BindPhoneActivity extends BaseToolBarActivity {

    public static final String MODE = "MODE";
    public static final String FROM = "FROM";

    public static class ThirdParty{
        public static final String THIRD_PARTY_ID = "THIRD_PARTY_ID";
        public static final String THIRD_PARTY_TYPE = "THIRD_PARTY_TYPE";
        public static final String THIRD_PARTY_USER_NAME = "THIRD_PARTY_USER_NAME";
        public static final String THIRD_PARTY_IMAGE_URL = "THIRD_PARTY_IMAGE_URL";
        public static final String THIRD_PARTY_TOKEN = "THIRD_PARTY_TOKEN";
    }

    public static final int MODE_BIND = 0;
    public static final int MODE_CHANGE = 1;
    private static final int STEP_INPUT_PHONE = 0;
    private static final int STEP_SUBMIT_INFO = 1;

    private TextView text_view_title_hint;
    private TextView text_view_content_hint;
    private TextView text_view_vcode_hint;
    private View view_count_down;
    private EditText edit_text;
    private Button button;
    private ProgressDialog progress_dialog;
    private ProgressDialog loginout_dialog;
    private EBTDialog loginout_confirm_dialog;

    private int mStep = STEP_INPUT_PHONE;
    private int mMode = MODE_BIND;
    private String mPhoneNumber;
    private String mValidateId;
    private String mFrom;
    private boolean mHasSend;

    private CountDownManager.CountDownListener mCountDownListener;
    private CountDownManager mCountDownManager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bind_phone);
        getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_TITLE);
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
    }

    @Override
    protected void init() {
        mCountDownManager = CountDownManager.getInstance();
        mMode = getIntent().getIntExtra(MODE, MODE_BIND);
        mFrom = getIntent().getStringExtra(FROM);
        text_view_vcode_hint = (TextView) this.findViewById(R.id.text_view_vcode_hint);
        text_view_title_hint = (TextView) this.findViewById(R.id.text_view_title_hint);
        text_view_content_hint = (TextView) this.findViewById(R.id.text_view_content_hint);
        edit_text = (EditText) this.findViewById(R.id.edit_text);
        button = (Button) this.findViewById(R.id.button);
        view_count_down = this.findViewById(R.id.view_count_down);

        view_count_down.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mCountDownManager.isCountingDown()){
                    ToastUtil.showToastD("请稍后再发送验证码");
                }else{
                    sendVerificationCodeRequest();
                }
            }
        });

        edit_text.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable editable) {
                updateButton();
            }
        });

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switch (mStep) {
                    case STEP_INPUT_PHONE:
                        mPhoneNumber = edit_text.getText().toString().trim();
                        checkIfPhoneNumberBound();
                        break;
                    case STEP_SUBMIT_INFO:
                        toSubmit();
                        break;
                }
            }
        });

        mCountDownListener = new CountDownListener() {
            @Override
            public void onTick(long remainMillisSecond) {
                int countdownSecond = (int) (remainMillisSecond / 1000);
                updateVCodeHint(String.valueOf(countdownSecond));
            }

            @Override
            public void onFinish() {
                updateVCodeHint("");
            }
        };
        mCountDownManager.setCountDownListener(mCountDownListener);

        initProgressDialog();
        updateTitle();
        updateHints();
        updateButton();
    }

    //点击下一步
    private void toStep1() {
        mStep = STEP_SUBMIT_INFO;
        edit_text.setText("");
        updateHints();
        updateButton();
        updateVCodeHint("");
    }

    //返回第一步
    private void toStep0() {
        mStep = STEP_INPUT_PHONE;
        edit_text.setText(mPhoneNumber);
        updateHints();
        updateButton();
        updateVCodeHint("");
    }

    //检查手机号是否已经被绑定
    private void checkIfPhoneNumberBound() {
        if (!NetUtils.isNetworkAvailable(this)) {
            ToastUtil.showToast(getString(R.string.network_fail));
            return;
        }
        showProgress(getString(R.string.check_if_bound));
        UserInfo userInfo = AppContext.getCurrentUser();
        String token = userInfo.getAccessToken();
        if (TextUtils.isEmpty(userInfo.getAccessToken())) {
            token = getIntent().getStringExtra(ThirdParty.THIRD_PARTY_TOKEN);
        }
        AccountHttps.getInstance().checkPhoneNumberIfBound(mPhoneNumber, token, getCheckPhoneIfBoundSubscriber());
    }

    private Observer getCheckPhoneIfBoundSubscriber() {
        return new Observer<BaseDataResult<AccountResponse>>() {
            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                ToastUtil.showCheckBindErrorMessage(null);
                hideProgress();
            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(BaseDataResult<AccountResponse> ifBindJson) {
                hideProgress();
                if (ifBindJson == null || ifBindJson.getData() == null) {
                    ToastUtil.showCheckBindErrorMessage(ifBindJson);
                    return;
                }
                if (ifBindJson.getData() != null) {
                    AccountResponse ifBind = ifBindJson.getData();
                    if (ifBind.isSuccess) {
                        //被占用
                        ToastUtil.showToastL("此手机号已经被占用");
                    }else{
                        //未被占用
                        toStep1();
                        if (!mCountDownManager.isCountingDown()){
                            sendVerificationCodeRequest();
                        }
                    }
                }
            }
        };
    }

    //发送验证码请求
    private void sendVerificationCodeRequest() {

        if (!NetUtils.isNetworkAvailable(this)){
            ToastUtil.showToast(getString(R.string.network_fail));
            return;
        }

        if (TextUtils.isEmpty(mPhoneNumber)){
            ToastUtil.showToastL("请输入手机号码");
            return;
        }

        showProgress("正在获取验证码...");
        mCountDownManager.startCountDown();
        mHasSend = true;
        //发送验证码请求
        AccountHttps.getInstance().sendValidateCode(mPhoneNumber, getSendVCodeSubscriber(), this);
    }

    private Observer getSendVCodeSubscriber() {
        return new Observer<BaseDataResult<ValidateCodeSendResponse>>() {
            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                ToastUtil.showSendVCodeErrorMessage(null);
                hideProgress();
            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(BaseDataResult<ValidateCodeSendResponse> responseJson) {
                hideProgress();
                if (responseJson == null || responseJson.getData() == null) {
                    ToastUtil.showSendVCodeErrorMessage(responseJson);
                    return;
                }
                if (responseJson.getData() != null) {
                    ValidateCodeSendResponse validateCodeSendResponse = responseJson.getData();
                    if (validateCodeSendResponse.isSuccess) {
                        mValidateId = validateCodeSendResponse.getValidateId();
                        updateTitleHint(mPhoneNumber);
                        toStep1();
                    }else{
                        ToastUtil.showSendVCodeErrorMessage(responseJson);
                    }
                }
            }
        };
    }

    //点击提交，检查验证是否通过
    private void toSubmit() {
        if (!NetUtils.isNetworkAvailable(this)){
            ToastUtil.showToast(getString(R.string.network_fail));
            return;
        }
        //校对验证码
        /*if (TextUtils.isEmpty(mValidateId)){
            ToastUtil.showToast("验证码无效，请重新获取");
            return;
        }*/
        //发送验证码
        AccountHttps.getInstance().checkValidateCode(
                mPhoneNumber,
                mValidateId,
                edit_text.getText().toString().trim(),
                getCheckVCodeSubscriber());
    }

    private Observer getCheckVCodeSubscriber() {
        return new Observer<BaseDataResult<ValidateCodeCheckResponse>>() {
            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                ToastUtil.showCheckVCodeErrorMessage(null);
                hideProgress();
            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(BaseDataResult<ValidateCodeCheckResponse> responseJson) {
                hideProgress();
                if (responseJson == null || responseJson.getData() == null) {
                    ToastUtil.showCheckVCodeErrorMessage(responseJson);
                    return;
                }
                if (responseJson.getData() != null) {
                    ValidateCodeCheckResponse validateCodeCheckResponse = responseJson.getData();
                    if (validateCodeCheckResponse.isSuccess) {
                        //验证成功，更换绑定的手机号
                        //新绑定或者更改绑定，都走这里
                        changeBindPhoneNumber();
                    }else{
                        ToastUtil.showCheckVCodeErrorMessage(responseJson);
                    }
                }
            }
        };
    }

    //更换绑定的手机号
    private void changeBindPhoneNumber(){
        if (!NetUtils.isNetworkAvailable(this)){
            ToastUtil.showToast(getString(R.string.network_fail));
            return;
        }
        switch (mMode){
            case MODE_BIND:
                showProgress("正在绑定的手机号...");
                break;
            case MODE_CHANGE:
                showProgress("正在更改绑定的手机号...");
                break;
        }
        UserInfo userInfo = AppContext.getCurrentUser();
        String token = userInfo.getAccessToken();
        if (TextUtils.isEmpty(userInfo.getAccessToken())) {
            token = getIntent().getStringExtra(ThirdParty.THIRD_PARTY_TOKEN);
        }
        AccountHttps.getInstance().bindPhoneNumber(mPhoneNumber, token, getBindPhoneNumberSubscriber());
    }

    private Observer getBindPhoneNumberSubscriber() {
        return new Observer<BaseDataResult<AccountResponse>>() {

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                ToastUtil.showToast(getString(R.string.change_bind_phone_failed));
                hideProgress();
            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(BaseDataResult<AccountResponse> responseJson) {

                if (responseJson == null || responseJson.getData() == null) {
                    ToastUtil.showToast(getString(R.string.change_bind_phone_failed));
                    hideProgress();
                    return;
                }
                if (responseJson.getData() != null) {
                    if (responseJson.getData().isSuccess) {
                        switch (mMode){
                            case MODE_BIND:
                                hideProgress();
                                if (LoginPresenter.class.getCanonicalName().equals(mFrom)){
                                    ToastUtil.showToastL("新的手机号码 "+ mPhoneNumber + " 绑定成功");
                                    showProgress("正在重新登录");
                                    thirdPartyLogin();
                                }else{
                                    ToastUtil.showToastL("新的手机号码 "+ mPhoneNumber + " 绑定成功，请重新登陆");
                                    logout();
                                }
                                break;
                            case MODE_CHANGE:
                                hideProgress();
                                //变更绑定，需要重新登录
                                ToastUtil.showToastL("新的手机号码 "+ mPhoneNumber + " 绑定成功，请重新登陆");
                                logout();
                                break;
                            default:
                                hideProgress();
                        }
                    }else{
                        hideProgress();
                        //验证失败
                        ToastUtil.showToastL(getString(R.string.change_bind_phone_failed));
                    }
                }else{
                    hideProgress();
                }
            }
        };
    }

    @Override
    public void onBackPressed() {
        //弹出是否退出登录对话框
        switch (mStep) {
            case STEP_INPUT_PHONE:
                switch (mMode){
                    case MODE_BIND:
                        if (SettingActivity.class.getCanonicalName().equals(mFrom)){
                            super.onBackPressed();
                            break;
                        }else {
                            logoutConfirm();
                            break;
                        }
                    case MODE_CHANGE:
                        super.onBackPressed();
                        break;
                }
                break;
            case STEP_SUBMIT_INFO:
                toStep0();
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(LoginEvent event) {
        if (event == null) {
            return;
        }
        if (!event.login){
            this.finish();
        }
    }

    public void showProgress(String message) {
        progress_dialog.setMessage(message);
        progress_dialog.show();
    }

    private void hideProgress(){
        progress_dialog.dismiss();
    }

    public void initProgressDialog() {
        progress_dialog = new ProgressDialog(BindPhoneActivity.this, R.style.LightDialog);
        progress_dialog.setIndeterminate(true);

        loginout_dialog = new ProgressDialog(this, R.style.LightDialog);
        loginout_dialog.setIndeterminate(true);
        loginout_dialog.setMessage(getResources().getString(R.string.login_outing));
    }

    private void logoutConfirm() {
        loginout_confirm_dialog = new EBTDialog();
        loginout_confirm_dialog.setMessage("手机号绑定为必须步骤，放弃绑定将无法使用" + getResources().getString(R.string.app_name) + "，确定放弃？");
        loginout_confirm_dialog.setRightButton("放弃", view -> logout());
        loginout_confirm_dialog.setLeftButton("取消", view -> loginout_confirm_dialog.dismiss());
        loginout_confirm_dialog.show(getSupportFragmentManager(), getClass().getSimpleName());
    }

    private void logout(){
        loginout_dialog.show();
        AppInitService.getEbtApi()
                .userLoginOut()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(response -> loginOutAction(), throwable -> loginOutAction());
    }

    private void loginOutAction() {
        AppContext.clearLoginInfo(this);
        EventBus.getDefault().post(new LoginEvent(false));
        toLoginActivity();
    }

    private void toLoginActivity(){
        Intent loginIntent = new Intent(this, LoginActivity.class);
        loginIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(loginIntent);
        finish();
    }

    private void updateVCodeHint(String countDownHint) {

        switch (mStep) {
            case STEP_INPUT_PHONE:
                view_count_down.setVisibility(View.GONE);
                break;
            case STEP_SUBMIT_INFO:
                view_count_down.setVisibility(View.VISIBLE);

                if(!mCountDownManager.isCountingDown()) {
                    //不在倒计时
                    if (TextUtils.isEmpty(countDownHint)) {
                        text_view_vcode_hint.setText(mHasSend ? "重新发送" : "获取验证码");
                        text_view_vcode_hint.setTextColor(getResources().getColor(R.color.btn_green_normal));
                    } else {
                        text_view_vcode_hint.setText("重新发送(" + countDownHint + ")");
                        text_view_vcode_hint.setTextColor(getResources().getColor(R.color.btn_green_disable));
                    }
                }else{
                    //正在倒计时
                    if (TextUtils.isEmpty(countDownHint)) {
                        text_view_vcode_hint.setText(mHasSend ? "重新发送" : "获取验证码");
                    } else {
                        text_view_vcode_hint.setText("重新发送(" + countDownHint + ")");
                    }
                    text_view_vcode_hint.setTextColor(getResources().getColor(R.color.btn_green_disable));
                }
                break;
        }
    }

    //更新view
    private void updateTitle(){
        switch (mMode) {
            case MODE_BIND:
                setTitle(R.string.bind_phone_title);
                break;
            case MODE_CHANGE:
                setTitle(R.string.change_phone_title);
                break;
        }
    }

    private void updateTitleHint(String phone) {
        String str1 = "已向手机号 ";
        String str2 = " 发送短信验证码";
        SpannableString spannableString = new SpannableString(str1 + phone + str2);

        ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#666666"));
        RelativeSizeSpan sizeSpan = new RelativeSizeSpan(1.2f);

        spannableString.setSpan(colorSpan, str1.length(), str1.length() + phone.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spannableString.setSpan(sizeSpan, str1.length(), str1.length() + phone.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

        text_view_title_hint.setText(spannableString);
    }

    private void updateHints() {
        switch (mStep) {
            case STEP_INPUT_PHONE:
                text_view_content_hint.setText("手机号码");
                edit_text.setHint("请输入手机号码");
                switch (mMode) {
                    case MODE_BIND:
                        text_view_title_hint.setText("为了您的账户安全，请绑定手机号");
                        break;
                    case MODE_CHANGE:
                        text_view_title_hint.setText("请输入想要更换后的手机号");
                        break;
                }
                break;
            case STEP_SUBMIT_INFO:
                text_view_content_hint.setText("验证码");
                edit_text.setHint("请输入验证码");
                break;
        }
    }

    private void updateButton() {
        String str = edit_text.getText().toString().trim();
        switch (mStep){
            case STEP_INPUT_PHONE:
                button.setText("下一步");
                if (DataValidation.checkMobile(str)) {
                    button.setEnabled(true);
                } else {
                    button.setEnabled(false);
                }
                break;
            case STEP_SUBMIT_INFO:
                button.setText("提交");
                if (DataValidation.checkVCode(str) && !TextUtils.isEmpty(mValidateId)) {
                    button.setEnabled(true);
                } else {
                    button.setEnabled(false);
                }
                break;
        }
    }

    /**
     * 第三方登录
     */
    private void thirdPartyLogin() {

        String thirdPartyId = getIntent().getStringExtra(BindPhoneActivity.ThirdParty.THIRD_PARTY_ID);
        String thirdPartyType = getIntent().getStringExtra(BindPhoneActivity.ThirdParty.THIRD_PARTY_TYPE);
        String thirdPartyUserName = getIntent().getStringExtra(BindPhoneActivity.ThirdParty.THIRD_PARTY_USER_NAME);
        String thirdPartyImageUrl = getIntent().getStringExtra(BindPhoneActivity.ThirdParty.THIRD_PARTY_IMAGE_URL);

        EBTAPI userApi = AppInitService.getEbtApi();
        Observable.just(Arrays.asList(thirdPartyId, thirdPartyType, thirdPartyUserName, thirdPartyImageUrl))
                .flatMap(lists -> userApi.getThirtyLogin(getThirtyLoginParam(lists.get(0), lists.get(1), lists.get(2), lists.get(3))))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(resultMsg -> {
                    hideProgress();
                    if (resultMsg != null && resultMsg.getData() != null) {
                        LoginPresenter.checkAndHandleLogin(BindPhoneActivity.this, resultMsg.getData());
                        finish();
                    } else {
                        logout();
                        ToastUtil.showToast("重新登录失败，请重新登录");
                    }
                }, throwable -> {
                    hideProgress();
                    logout();
                    ToastUtil.showToast("重新登录失败，请重新登录" + throwable.getMessage());
                });
    }

    private ThirtyLoginParam getThirtyLoginParam(String thirtyId, String thiryType, String userName, String imageUrl) {
        ThirtyLoginParam loginParam = new ThirtyLoginParam();
        loginParam.UserName = thirtyId;
        loginParam.ReqestDevice = ConfigData.REQUEST_DEVICE + "-" + EBTGetAdviceInfo.getMetadata(AppContext.getInstance(), "TD_CHANNEL_ID");
        loginParam.APKVersion = EBTGetAdviceInfo.getAppVersionName();
        loginParam.CardName = userName;
        loginParam.BindType = thiryType;
        loginParam.PortraitAddress = imageUrl;
        loginParam.CreateBy = ConfigData.REQUEST_DEVICE + "-" + EBTGetAdviceInfo.getMetadata(AppContext.getInstance(), "TD_CHANNEL_ID");
        loginParam.model = Build.MODEL;
        loginParam.Mac = EBTGetAdviceInfo.getMacAddress();
        loginParam.DeviceSN = EBTGetAdviceInfo.getDeviceId();
        return loginParam;
    }
}